/* *
 * 压缩字符串
 */
export function compress(strNormalString) {
  console.log(' 压缩前长度： ' + strNormalString.length);
  let strCompressedString = '';
  let ht = [];
  for (let i = 0; i < 128; i++) {
    ht[i] = i;
  }

  let used = 128;
  let intLeftOver = 0;
  let intOutputCode = 0;
  let pCode = 0;
  let cCode = 0;
  let k = 0;

  for (let i = 0; i < strNormalString.length; i++) {
    cCode = strNormalString.charCodeAt(i);
    k = (pCode << 8) | cCode;
    if (ht[k] != null) {
      pCode = ht[k];
    } else {
      intLeftOver += 12;
      intOutputCode <<= 12;
      intOutputCode |= pCode;
      pCode = cCode;
      if (intLeftOver >= 16) {
        strCompressedString += String.fromCharCode(intOutputCode >> (intLeftOver - 16));
        intOutputCode &= Math.pow(2, intLeftOver - 16) - 1;
        intLeftOver -= 16;
      }
      if (used < 4096) {
        used++;
        ht[k] = used - 1;
      }
    }
  }

  if (pCode != 0) {
    intLeftOver += 12;
    intOutputCode <<= 12;
    intOutputCode |= pCode;
  }

  if (intLeftOver >= 16) {
    strCompressedString += String.fromCharCode(intOutputCode >> (intLeftOver - 16));
    intOutputCode &= Math.pow(2, intLeftOver - 16) - 1;
    intLeftOver -= 16;
  }

  if (intLeftOver > 0) {
    intOutputCode <<= 16 - intLeftOver;
    strCompressedString += String.fromCharCode(intOutputCode);
  }

  console.log(strCompressedString + ' 压缩后长度： ' + strCompressedString.length);
  return strCompressedString;
}

/* *
 * 解压缩字符串
 */
export function decompress(strCompressedString) {
  let strNormalString = '';
  let ht = [];

  for (let i = 0; i < 128; i++) {
    ht[i] = String.fromCharCode(i);
  }

  let used = 128;
  let intLeftOver = 0;
  let intOutputCode = 0;
  let cCode = 0;
  let pCode = 0;
  let key = 0;

  for (let i = 0; i < strCompressedString.length; i++) {
    intLeftOver += 16;
    intOutputCode <<= 16;
    intOutputCode |= strCompressedString.charCodeAt(i);

    while (1) {
      if (intLeftOver >= 12) {
        cCode = intOutputCode >> (intLeftOver - 12);
        if (typeof (key = ht[cCode]) != 'undefined') {
          strNormalString += key;
          if (used > 128) {
            ht[ht.length] = ht[pCode] + key.substr(0, 1);
          }
          pCode = cCode;
        } else {
          key = ht[pCode] + ht[pCode].substr(0, 1);
          strNormalString += key;
          ht[ht.length] = ht[pCode] + key.substr(0, 1);
          pCode = ht.length - 1;
        }

        used++;
        intLeftOver -= 12;
        intOutputCode &= Math.pow(2, intLeftOver) - 1;
      } else {
        break;
      }
    }
  }
  console.log('解压缩后长度：' + strNormalString.length);
  return strNormalString;
}
